﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using log4net;
using TanHungViet.Helper;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace TanHungViet.Web.Models
{
    public partial class Product
    {
        public string ProductName { get; set; }
        public string ProductName2 { get; set; }
        public string ProductDescrip { get; set; }
        public string ProductDescrip2 { get; set; }
        public string ProductDetail { get; set; }
        public string ProductDetail2 { get; set; }
        public int Count { get; set; }
        public decimal Cost { get; set; }

        public Product() { }
        public Product(string version, DateTime updateDate, decimal price, string link,
            string imageUrl, bool inHomePage, string name1, string name2, string descrip1,
            string descrip2, string detail1, string detail2)
        {
            ProductVersion = version;
            UpdateDate = updateDate;
            ProductPrice = price;
            DownloadLink = link;
            ProductImage = imageUrl;
            InHomePage = inHomePage;

            ProductName = name1;
            ProductName2 = name2;
            ProductDescrip = descrip1;
            ProductDescrip2 = descrip2;
            ProductDetail = detail1;
            ProductDetail2 = detail2;
            Count = 0;
            Cost = 0;
        }
    }

    [Bind(Exclude = "ProductID")]
    public class ProductValidation
    {
        [Required(ErrorMessage = "Tên sản phẩm  không được bỏ trống")]
        [StringLength(200, ErrorMessage = "Tên sản phẩm không được vượt quá 200 ký tự!")]
        public string ProductName { get; set; }
    }


    public class ProductRepository
    {
        private static ILog _logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private DBTanHungVietEntities _db;

        public ProductRepository(DBTanHungVietEntities entity)
        {
            _db = entity;
        }

        public IQueryable<Product> GetListProductByContentCode(string contentCode)
        {
            try
            {
                _logger.InfoFormat("Begin GetListProductByContentCode({0})", contentCode);

                var content = _db.Content.FirstOrDefault(b => b.ContentCode == contentCode);
                if (content == null)
                    return null;

                var list = from b in _db.Product
                           where b.ContentID == content.ContentID
                           select b;

                foreach (var item in list)
                {
                    var tempVN = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 1);
                    if (tempVN == null)
                        _logger.Error("Product has no detail");
                    else
                    {
                        item.ProductName = tempVN.ProductName ?? string.Empty;
                        item.ProductDescrip = tempVN.ProductDescrip ?? string.Empty;
                        item.ProductDetail = tempVN.ProductDetail1 ?? string.Empty;
                    }

                    var tempUS = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 2);
                    if (tempUS != null)
                    {
                        item.ProductName2 = tempUS.ProductName ?? string.Empty;
                        item.ProductDescrip2 = tempUS.ProductDescrip ?? string.Empty;
                        item.ProductDetail2 = tempUS.ProductDetail1 ?? string.Empty;
                    }
                }

                _logger.Info("End GetListProductByContentCode ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public List<Product> GetListProductByListID(List<int> listID)
        {
            try
            {
                _logger.Info("Begin GetListProductByListID()");

                List<Product> result = new List<Product>();
                var list = from b in _db.Product
                           select b;

                foreach (var item in list)
                    if (listID.Contains(item.ProductID))
                        result.Add(item);

                foreach (var item in result)
                {
                    var tempVN = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 1);
                    if (tempVN == null)
                        _logger.Error("Product has no detail");
                    else
                    {
                        item.ProductName = tempVN.ProductName ?? string.Empty;
                        item.ProductDescrip = tempVN.ProductDescrip ?? string.Empty;
                        item.ProductDetail = tempVN.ProductDetail1 ?? string.Empty;
                    }

                    var tempUS = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 2);
                    if (tempUS != null)
                    {
                        item.ProductName2 = tempUS.ProductName ?? string.Empty;
                        item.ProductDescrip2 = tempUS.ProductDescrip ?? string.Empty;
                        item.ProductDetail2 = tempUS.ProductDetail1 ?? string.Empty;
                    }
                }

                _logger.Info("End GetListProductByListID ....");
                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Product> GetListProductForHomePage()
        {
            try
            {
                _logger.Info("Begin GetListProductForHomePage()");

                var list = from b in _db.Product
                           where b.InHomePage == true
                           select b;

                foreach (var item in list)
                {
                    var tempVN = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 1);
                    if (tempVN == null)
                        _logger.Error("Product has no detail");
                    else
                    {
                        item.ProductName = tempVN.ProductName ?? string.Empty;
                        item.ProductDescrip = tempVN.ProductDescrip ?? string.Empty;
                        item.ProductDetail = tempVN.ProductDetail1 ?? string.Empty;
                    }

                    var tempUS = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 2);
                    if (tempUS != null)
                    {
                        item.ProductName2 = tempUS.ProductName ?? string.Empty;
                        item.ProductDescrip2 = tempUS.ProductDescrip ?? string.Empty;
                        item.ProductDetail2 = tempUS.ProductDetail1 ?? string.Empty;
                    }
                }

                _logger.Info("End GetListProductForHomePage ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Product> GetFullListProduct()
        {
            try
            {
                _logger.Info("Begin GetFullListProduct()");

                var list = from b in _db.Product
                           select b;

                foreach (var item in list)
                {
                    var tempVN = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 1);
                    if (tempVN == null)
                        _logger.Error("Product has no detail");
                    else
                    {
                        item.ProductName = tempVN.ProductName ?? string.Empty;
                        item.ProductDescrip = tempVN.ProductDescrip ?? string.Empty;
                        item.ProductDetail = tempVN.ProductDetail1 ?? string.Empty;
                    }

                    var tempUS = _db.ProductDetail.FirstOrDefault(
                        b => b.ProductID == item.ProductID
                            && b.LanguageID == 2);
                    if (tempUS != null)
                    {
                        item.ProductName2 = tempUS.ProductName ?? string.Empty;
                        item.ProductDescrip2 = tempUS.ProductDescrip ?? string.Empty;
                        item.ProductDetail2 = tempUS.ProductDetail1 ?? string.Empty;
                    }
                }

                _logger.Info("End GetFullListProduct()");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Product GetFullProductByID(int id)
        {
            try
            {
                _logger.InfoFormat("Begin GetFullProductByID({0})", id);

                var product = _db.Product.FirstOrDefault(b => b.ProductID == id);
                if (product == null)
                    return null;

                var detail = _db.ProductDetail.FirstOrDefault(b => b.ProductID == product.ProductID
                    && b.LanguageID == 1);
                if (detail == null)
                    return null;
                else
                {
                    product.ProductName = detail.ProductName ?? string.Empty;
                    product.ProductDescrip = detail.ProductDescrip ?? string.Empty;
                    product.ProductDetail = detail.ProductDetail1 ?? string.Empty;
                }

                detail = _db.ProductDetail.FirstOrDefault(b => b.ProductID == product.ProductID
                    && b.LanguageID == 2);
                if (detail != null)
                {
                    product.ProductName2 = detail.ProductName ?? string.Empty;
                    product.ProductDescrip2 = detail.ProductDescrip ?? string.Empty;
                    product.ProductDetail2 = detail.ProductDetail1 ?? string.Empty;
                }

                _logger.Info("End GetFullProductByID ....");
                return product;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Product GetFullProductByCode(string code)
        {
            try
            {
                _logger.InfoFormat("Begin GetFullProductByCode({0})", code);

                var product = _db.Product.FirstOrDefault(b => b.ProductCode == code);
                if (product == null)
                    return null;

                var detail = _db.ProductDetail.FirstOrDefault(b => b.ProductID == product.ProductID
                    && b.LanguageID == 1);
                if (detail == null)
                    return null;
                else
                {
                    product.ProductName = detail.ProductName ?? string.Empty;
                    product.ProductDescrip = detail.ProductDescrip ?? string.Empty;
                    product.ProductDetail = detail.ProductDetail1 ?? string.Empty;
                }

                detail = _db.ProductDetail.FirstOrDefault(b => b.ProductID == product.ProductID
                    && b.LanguageID == 2);
                if (detail != null)
                {
                    product.ProductName2 = detail.ProductName ?? string.Empty;
                    product.ProductDescrip2 = detail.ProductDescrip ?? string.Empty;
                    product.ProductDetail2 = detail.ProductDetail1 ?? string.Empty;
                }

                _logger.Info("End GetFullProductByCode ....");
                return product;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void AddNewProduct(Product newProduct, string parentContentCode, bool hasImage)
        {
            try
            {
                _logger.InfoFormat("Begin AddNewProduct({0})", parentContentCode);

                var content = _db.Content.FirstOrDefault(b => b.ContentCode == parentContentCode);
                if (content == null)
                    return;

                newProduct.ContentID = content.ContentID;
                // kiem tra file code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    Product checkProduct = _db.Product.FirstOrDefault(b => b.ProductCode == newProduct.ProductCode);
                    if (checkProduct != null)
                    {
                        newProduct.ProductCode += "-1";
                        _logger.InfoFormat("New file code is ({0})", newProduct.ProductCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);
                _db.AddToProduct(newProduct);
                _db.SaveChanges();

                string name = string.IsNullOrEmpty(newProduct.ProductName) ? string.Empty : newProduct.ProductName; 
                string descrip = newProduct.ProductDescrip;
                string detail = newProduct.ProductDetail;
                newProduct = _db.Product.FirstOrDefault(b => b.ProductCode == newProduct.ProductCode);
                // cap nhat content image
                if (hasImage)
                {
                    string contentImage = newProduct.ProductImage;
                    string[] arrString = contentImage.Split(new char[] { '.' });
                    newProduct.ProductImage = newProduct.ProductID.ToString() + "." + arrString[1];
                }

                ProductDetail productDetail = new ProductDetail();
                productDetail.ProductID = newProduct.ProductID;
                productDetail.LanguageID = 1;
                productDetail.ProductName = name;
                productDetail.ProductDescrip = descrip;
                productDetail.ProductDetail1 = detail;
                _db.AddToProductDetail(productDetail);
                _db.SaveChanges();
             
                _logger.InfoFormat("End AddNewProduct({0})", parentContentCode);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void UpdateProduct(Product updateProduct)
        {
            try
            {
                _logger.InfoFormat("Begin UpdateProduct({0})", updateProduct.ProductID.ToString());

                var product = _db.Product.FirstOrDefault(b => b.ProductID == updateProduct.ProductID);
                if (product == null)
                    return;

                if (!string.IsNullOrEmpty(updateProduct.ProductImage))
                    product.ProductImage = updateProduct.ProductImage;
                product.ProductVersion = updateProduct.ProductVersion;
                product.UpdateDate = updateProduct.UpdateDate;
                product.ProductPrice = updateProduct.ProductPrice;
                product.DownloadLink = updateProduct.DownloadLink;
                product.InHomePage = updateProduct.InHomePage;
                product.ProductCode = updateProduct.ProductCode;
                // kiem tra file code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    Product checkProduct = _db.Product.FirstOrDefault(b => b.ProductCode == updateProduct.ProductCode);
                    if (checkProduct != null)
                    {
                        updateProduct.ProductCode += "-1";
                        _logger.InfoFormat("New file code is ({0})", updateProduct.ProductCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);

                ProductDetail productDetail = _db.ProductDetail.FirstOrDefault(b => b.ProductID == updateProduct.ProductID
                    && b.LanguageID == 1);
                if (productDetail != null)
                {
                    productDetail.ProductName = updateProduct.ProductName;
                    productDetail.ProductDescrip = updateProduct.ProductDescrip;
                    productDetail.ProductDetail1 = updateProduct.ProductDetail;
                }

                _db.SaveChanges();
                _logger.InfoFormat("End UpdateProduct({0})", updateProduct.ProductID.ToString());
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public string DeleteProducts(string lstId)
        {
            try
            {
                _logger.InfoFormat("Begin DeleteProducts({0})", lstId);
                string result = string.Empty;
                string[] arr = lstId.Split('-');

                foreach (string id in arr)
                {
                    if (id.Length > 0)
                    {
                        int idDelete = int.Parse(id);
                        Product deleteProduct = _db.Product.FirstOrDefault(b => b.ProductID == idDelete);
                        if (deleteProduct != null)
                        {
                            if (!string.IsNullOrEmpty(deleteProduct.ProductImage))
                                result += deleteProduct.ProductImage + "-";
                            ProductDetail deleteDetail = _db.ProductDetail.FirstOrDefault(b => b.ProductID == idDelete &&
                                b.LanguageID == 1);
                            if (deleteDetail != null)
                                _db.DeleteObject(deleteDetail);

                            _db.DeleteObject(deleteProduct);
                        }
                    }
                }

                _db.SaveChanges();
                _logger.Info("End DeleteProducts()");

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void DeleteProductType(string code)
        {
            try
            {
                _logger.InfoFormat("Begin DeleteProductType({0})", code);

                Content content = _db.Content.FirstOrDefault(b => b.ContentCode == code);
                if (content == null)
                    return;

                // xoa menu
                Menu menu = _db.Menu.FirstOrDefault(b => b.ContentID == content.ContentID);
                if (menu != null)
                {
                    MenuDetail detail1 = _db.MenuDetail.FirstOrDefault(b => b.MenuID == menu.MenuID
                        && b.LanguageID == 1);
                    if (detail1 != null)
                        _db.DeleteObject(detail1);

                    MenuDetail detail2 = _db.MenuDetail.FirstOrDefault(b => b.MenuID == menu.MenuID
                       && b.LanguageID == 2);
                    if (detail2 != null)
                        _db.DeleteObject(detail2);

                    _db.DeleteObject(menu);
                }

                // xoa cac san pham con
                var products = _db.Product.Where(b => b.ContentID == content.ContentID);
                foreach (Product n in products)
                {
                    ProductDetail detail1 = _db.ProductDetail.FirstOrDefault(b => b.ProductID == n.ProductID
                        && b.LanguageID == 1);
                    if (detail1 != null)
                        _db.DeleteObject(detail1);

                    ProductDetail detail2 = _db.ProductDetail.FirstOrDefault(b => b.ProductID == n.ProductID
                        && b.LanguageID == 2);
                    if (detail2 != null)
                        _db.DeleteObject(detail2);

                    _db.DeleteObject(n);
                }

                _db.DeleteObject(content);
                _db.SaveChanges();
                _logger.Info("End DeleteProductType()");
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }
    }
}